package com.lyf.security.login.service.impl;

import com.lyf.data.structure.jpa.entity.crm.*;
import com.lyf.security.dao.crm.*;
import com.lyf.security.login.service.LoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.*;

/**
 * @AUTHOR LYF
 * @DATE 2022/1/21
 * @VERSION 1.0
 * @DESC
 */
@Service
public class LoginServiceImpl implements LoginService {
    @Autowired
    UserDao userDao;
    @Autowired
    RoleDao roleDao;
    @Autowired
    UserRoleDao userRoleDao;
    @Autowired
    RolePermissionDao rolePermissionDao;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    PermissionDao permissionDao;



    @Override
    public boolean validate(String username, String password) {
        List<CusUserEntity> userList = userDao.findByUsername(username);
        if(userList==null||userList.size()==0||userList.size()>1){
            return false;
        }
        String pwd = userList.get(0).getPassword();
        if(!pwd.equals(password)){
            return false;
        }
        return true;
    }

    @Override
    public boolean saveToken(String token,  String username) {
        redisTemplate.opsForValue().set("token:"+token,username);//其实也完全可以直接用token查权限,无需转换？
        //List<CusPermissionEntity> permissions=listPermissions(username);
        List<String> permissions=listPermissions(username);
        String usrPermissionList = "userPermissionList:"+username;//Stream中好像不能？
        //设置时效
        redisTemplate.expire(usrPermissionList, Duration.ofSeconds(60*60));
        redisTemplate.expire("token:"+token,Duration.ofSeconds(60*60));
        //将权限列表加入redis
        if(permissions==null){
            redisTemplate.opsForList().leftPush(usrPermissionList,null);// 权限为空
            return true;
        }
        System.out.println("Save token...");
//        permissions.forEach(permission->{
//            redisTemplate.opsForList().leftPush(usrPermissionList,permission);
//        }); //违背原子性？
         for(String permission:permissions){
             redisTemplate.opsForList().leftPush(usrPermissionList,permission);
         }
        return true;
    }

    @Override
    public List<String> listPermissions(String username) { ///CusPermissionEntity 返回Mark，方便Redis，认证时处理
        // 若采用username，则此处的开销过大
        List<CusUserEntity> userEntityList = userDao.findByUsername(username);
        if(userEntityList.size()!=1){// size()==0,不能使用null来表示    ||userEntityList.size()>1
            System.out.println("权限为空...");
            return null;
        }

        System.out.println("查询权限，关联表查询");
        Integer userId=userEntityList.get(0).getId();
        List<UserRoleEntity> userRoleList = userRoleDao.findByUserId(userId);// 一般只对应一个角色
        //List<Integer> roleList = new ArrayList<>();
        // 角色有公共的权限
        Set<Integer> permissionSet = new HashSet<>();

        for(UserRoleEntity u:userRoleList){
            List<RolePermissionEntity> permissionEntityList = rolePermissionDao.findByRoleId(u.getRoleId());
            for(RolePermissionEntity u1:permissionEntityList){
                permissionSet.add(u1.getPermission());
            }
        }

        //List<Integer> permissionList = permissionSet.stream().toList();
        List<String> permissionList = new LinkedList<>();
        //List<CusPermissionEntity> permissionList = new LinkedList<>();// 需要只返回Mark吗?
        List<CusPermissionEntity> allPermissionList = permissionDao.findAll();
        for(CusPermissionEntity u:allPermissionList){
            if(permissionSet.contains(u.getId()))
                 permissionList.add(u.getMark());
        }
        return permissionList;
    }
}
